package com.example.fileprovider;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import com.example.office.CryptUtils;

import java.io.*;
import java.util.regex.Pattern;

/**
 * description: 自定义的ContentProvider，用于处理WebView的资源加载请求。
 *
 * @date: 2014年5月8日
 * @author: wzq
 */
public class FileProvider extends ContentProvider {
    public static final String AUTH = "org.example.wv3";

    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode) {

        String filePath = uri.getPath();
        LogMgr.d("fetching:uri = " + uri);
        LogMgr.d("filePath = " + filePath);

        // 文件夹
        if(new File(filePath).isDirectory()) {
            LogMgr.e("file id dir =" + filePath);
            return null;
        }

        // 根据path 来进行处理
        ParcelFileDescriptor parcel = null;
        InputStream in = null;

        // case doc file
        try {

            // docx file
            if(filePath.contains("docx") && !isImageFile(filePath)) {
                // TODO:
                LogMgr.d("docx file");
                Htmlable docx2Html = new Docx2Html(filePath);
                if(docx2Html.convertToHtml()) {
                    in = docx2Html.getHtmlInputStream();
                }

            }
            // doc file
            else if(filePath.contains("doc") && !isImageFile(filePath)) {
                LogMgr.d("doc file");
                Htmlable doc2Html = new Doc2Html(filePath);
                if(doc2Html.convertToHtml()) {
                    in = doc2Html.getHtmlInputStream();
                }
            }

            // xlsx file
            else if(filePath.contains("xlsx") && !isImageFile(filePath)) {
                LogMgr.d("xlsx file");
                Htmlable xlsx2Html = new Xlsx2Html(filePath);
                if(xlsx2Html.convertToHtml()) {
                    in = xlsx2Html.getHtmlInputStream();
                }

            }

            // xls file
            else if(filePath.contains("xls") && !isImageFile(filePath)) {
                LogMgr.d("xls file");
                Htmlable xls2Html = new Xls2Html(filePath);
                if(xls2Html.convertToHtml()) {
                    in = xls2Html.getHtmlInputStream();
                    in = checkStreamContent(in);
                }
            }

            //
            else {
                in = new FileInputStream(new File(filePath));
            }
            if(in != null) {
                parcel = pipeFrom(in);
            }
        } catch(FileNotFoundException e) {
            LogMgr.e("file not found : uri=" + uri);
        } catch(IOException e) {
            LogMgr.e("Stream to ParcelFileDescriptor error " + e.toString());
        }

        if(parcel == null) {
            LogMgr.d("null parcel");
        }
        return parcel;
    }

    //endWith .jpg .jpeg .png .gif
    private static final String PATTERN_IMAGE = "\\w{1,}\\.(jpg|jpeg|png|gif)$";
    private static final Pattern PATTERN = Pattern.compile(PATTERN_IMAGE);
    public boolean isImageFile(String filePath) {
        return PATTERN.matcher(filePath).find();
    }

    @Override
    public boolean onCreate() {
        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        throw new UnsupportedOperationException("Not supported by this provider");
    }

    @Override
    public String getType(Uri uri) {
        throw new UnsupportedOperationException("Not supported by this provider");
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        throw new UnsupportedOperationException("Not supported by this provider");
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        throw new UnsupportedOperationException("Not supported by this provider");
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        throw new UnsupportedOperationException("Not supported by this provider");
    }


    public static ParcelFileDescriptor pipeFrom(InputStream inputStream) throws IOException {
        ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
        ParcelFileDescriptor readSide = pipe[0];
        ParcelFileDescriptor writeSide = pipe[1];
        // start the transfer thread
        new TransferThread(inputStream, new ParcelFileDescriptor.AutoCloseOutputStream(writeSide)).start();
        return readSide;
    }

    static class TransferThread extends Thread {
        final InputStream mIn;
        final OutputStream mOut;

        TransferThread(InputStream in, OutputStream out) {
            super("ParcelFileDescriptor Transfer Thread");
            mIn = in;
            mOut = out;
            setDaemon(true);
        }

        @Override
        public void run() {
            byte[] buf = new byte[1024];
            int len;

            try {
                while((len = mIn.read(buf)) > 0) {
                    mOut.write(buf, 0, len);
                }
                mOut.flush(); // just to be safe
            } catch(IOException e) {
                LogMgr.e("TransferThread " + e.toString());
            } finally {
                try {
                    mIn.close();
                } catch(IOException e) {
                }
                try {
                    mOut.close();
                } catch(IOException e) {
                }
            }
        }
    }


    private InputStream checkStreamContent(InputStream is) {
        ByteArrayInputStream stream = null;
        try {
            String str = CryptUtils.stream2String(is, "utf8");
            LogMgr.d(str);
            stream = new ByteArrayInputStream(CryptUtils.string2Bytes(str, "utf8"));
        } catch(IOException e) {
            e.printStackTrace();
        }

        return stream;
    }
}
